using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;

namespace demowebsocket
{
    public class WebSocketsManager
    {
        public ConcurrentDictionary<string, WebSocket> Clients = new ConcurrentDictionary<string, WebSocket>();

        private ILogger<WebSocketsManager> logger;
        public WebSocketsManager(ILogger<WebSocketsManager> logger)
        {
            this.logger = logger;
        }

        public WebSocketsManager RemoveClient(WebSocket client)
        {

            var key=Clients.FirstOrDefault(x => x.Value == client);
            Clients.TryRemove(key);
            logger.LogInformation($"client {key.Key} connect");
            return this;
        }
        
        public WebSocketsManager AddClient(WebSocket client)
        {
            var id = Guid.NewGuid().ToString();
            Clients.TryAdd(id, client);
            logger.LogInformation($"client {id} connect");
            return this;
        }

        private async Task SendMessageToClient(WebSocket socket, string msg)
        {
            if (socket.State == WebSocketState.Open)
            {
                await socket.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes(msg)), WebSocketMessageType.Text,
                    true, CancellationToken.None);
            }
        }

        public async Task SendMessageToClient(string clientId,string msg)
        {
            var client=Clients.FirstOrDefault(x => x.Key == clientId).Value;
            await this.SendMessageToClient(client,msg);
        }

        public async Task SendMessageToAll(string msg,WebSocket clientSelf)
        {

            var clientId = Clients.FirstOrDefault(x => x.Value == clientSelf).Key;
            msg = $"{clientId} say:{msg}";
            foreach (var client in Clients.Values)
            {
                if(client==clientSelf) continue;
                await this.SendMessageToClient(client, msg);
            }
        }
    }
}